package com.patui.Weibo;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;

import com.patui.ImageProcessor.ScaleImageProcessor;
import com.patui.ImageProcessor.ScaleType;
import com.patui.Utils.ImageUtils;
import com.patui.Utils.PLog;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
public class Utility {
	public final static String TAG="@___Patui.Utility";
	private static WeiboParameters mRequestHeader = new WeiboParameters();
	private static HttpHeaderFactory mAuth;
	private static Token mToken = null;
	public static final String BOUNDARY = "7cd4a6d158c";
    public static final String MP_BOUNDARY = "--" + BOUNDARY;
    public static final String END_MP_BOUNDARY = "--" + BOUNDARY + "--";
    public static final String MULTIPART_FORM_DATA = "multipart/form-data";
    public static final String HTTPMETHOD_POST = "POST";
    public static final String HTTPMETHOD_GET  = "GET";
    public static final String HTTPMETHOD_DELETE  = "DELETE";
    private static final int SET_CONNECTION_TIMEOUT = 50000;
    private static final int SET_SOCKET_TIMEOUT = 200000;

	public static void setTokenObject(Token token){
		mToken = token;
	}		
	public static void setAuthorization(HttpHeaderFactory auth){
		mAuth = auth;
	}
	
	public static void setHeader(String httpMethod, HttpUriRequest request, WeiboParameters postParam, String url, Token token) 
		throws WeiboException{
		if(!isBundleEmpty(mRequestHeader))
		{
			for(int mi = 0; mi < mRequestHeader.size(); mi++){
				String key = mRequestHeader.getKey(mi);
				request.setHeader(key, mRequestHeader.getValue(key));
			}
		}
		//用到请求头,拼装请求参数
		if(!isBundleEmpty(postParam))
		{
			String authHeader = mAuth.getWeiboAuthHeader(httpMethod, url, postParam, 
					Weibo.APP_KEY, Weibo.APP_SECRET, token);
			request.setHeader("Authorization", authHeader);
		}
	}
	
	public static boolean isBundleEmpty(WeiboParameters bundle){
		if(bundle == null || bundle.size() == 0){
			return true;
		}
		return false;
	}
	
	public static void setRequestHeader(String key, String value){
		mRequestHeader.add(key, value);
	}
	public static void setRequestHeader(WeiboParameters params){
		mRequestHeader.addAll(params);
	}
	public static void clearRequestHeader(){
		mRequestHeader.clear();
		
	}
    public static String encodePostBody(Bundle parameters, String boundary) {
        if (parameters == null) return "";
        StringBuilder sb = new StringBuilder();
        for (String key : parameters.keySet()) 
        {
            if (parameters.getByteArray(key) != null) 
            {
                continue;
            }
            sb.append("Content-Disposition: form-data; name=\"" + key +
                    "\"\r\n\r\n" + parameters.getString(key));
            sb.append("\r\n" + "--" + boundary + "\r\n");
        }

        return sb.toString();
    }

    //parameters转Url
    public static String encodeUrl(WeiboParameters parameters) {
        if (parameters == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        boolean firstBool = true;
        for (int mi = 0; mi < parameters.size(); mi++) 
        {
            if (firstBool)
            {
            	firstBool = false; 
            }
            else sb.append("&");
            sb.append(URLEncoder.encode(parameters.getKey(mi)) + "=" +
            URLEncoder.encode(parameters.getValue(mi)));
        }
        return sb.toString();
    }

    //Url转parameters
    public static Bundle decodeUrl(String s) {
        Bundle params = new Bundle();
        if (s != null) 
        {
            String array[] = s.split("&");
            for (String parameter : array) 
            {
                String v[] = parameter.split("=");
                params.putString(URLDecoder.decode(v[0]),URLDecoder.decode(v[1]));
            }
        }
        return params;
    }

    public static Bundle parseUrl(String url) {
        url = url.replace("fbconnect", "http");
        try {
            URL u = new URL(url);
            Bundle b = decodeUrl(u.getQuery());
            b.putAll(decodeUrl(u.getRef()));
            return b;
        } catch (MalformedURLException e) {
            return new Bundle();
        }
    }

    public static UrlEncodedFormEntity getPostParamters(Bundle bundle) throws WeiboException{
		if(bundle == null || bundle.isEmpty()){
			return null;
		}
		try {
			List<NameValuePair> form = new ArrayList<NameValuePair>();
			for(String key: bundle.keySet()){
				form.add(new BasicNameValuePair(key, bundle.getString(key)));
			}
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, "UTF-8");
			return entity;
		} catch (UnsupportedEncodingException e) {
			throw new WeiboException(e);
		}
	}
    
    public static String openUrl(Context context, String url, String method, WeiboParameters postParams,  
    		Token token) throws WeiboException{
    	String response ="";
    	String file = "";
    	//检查有没有图片
    	for(int mi = 0; mi < postParams.size(); mi++)
    	{
    		String key = postParams.getKey(mi);
    		if(key.equals("pic"))
    		{
    			file = postParams.getValue(key);
    			postParams.remove(key);
    			break;
    		}
    	}
    	//如果是没有图片
    	if(TextUtils.isEmpty(file))
    	{
    		response = openUrl(context, url, method, postParams, null, token);
    	}
    	//如果有图片
    	else
    	
    	{
    		response = openUrl(context, url, method, postParams, file, token);
    	}
    	
    	return response;
    }
    
    //Oauth认证,获取request的时候,token为null
    public static String openUrl(Context context, String url, String method, WeiboParameters postParams,  
    		String file, Token token)throws WeiboException {
	    		String result = "";
		    	try {
		    	HttpClient client = getHttpClient(context);
		    	HttpUriRequest request = null;
		    	//其实这里是一个封装,因为无论HttpGet还是HttpPost方法都实现了HttpUriRequest接口
		    	ByteArrayOutputStream byteArrayOutStream = null;
		    	//如果是GET方式
		    	if(method.equals("GET"))
		    	{
		    		url = url + "?" + encodeUrl(postParams);
		    		HttpGet get = new HttpGet(url);
		    		request = get;
		    	}
		    	//如果是POST方式
		    	else if(method.equals("POST"))
		    	{	
		    		HttpPost post = new HttpPost(url);	
		    		byte[] data = null;
		    		byteArrayOutStream = new ByteArrayOutputStream(1024 * 50);
				    //上传图片
				    if(!TextUtils.isEmpty(file)){
				    	post.setHeader("Content-Type",MULTIPART_FORM_DATA+";boundary="+BOUNDARY);
				    	//文字部分
				    	Utility.paramToUpload(byteArrayOutStream, postParams);
				    	Bitmap bm = ImageUtils.getBitmap(file);
				    	//图片部分
				    	Utility.imageToUpload(byteArrayOutStream, bm);
				    }
				    //上传文字
				   else
				    {
					    post.setHeader("Content-Type", "application/x-www-form-urlencoded");
				    	String postParamStr= encodeParameters(postParams);
					    data = postParamStr.getBytes("UTF-8");
					    byteArrayOutStream.write(data);
				    }
				    data = byteArrayOutStream.toByteArray();
				    byteArrayOutStream.close();
				    //设置实体
				    ByteArrayEntity formEntity = new ByteArrayEntity(data);
		    		post.setEntity(formEntity);
		    		request = post;
		    	}
		    	else if(method.equals("DELETE"))
		    	{
		    		request = new HttpDelete(url);
		    	}
		    	setHeader(method, request, postParams, url, token);
		    	HttpResponse response = client.execute(request);
		    	StatusLine status = response.getStatusLine();
		    	int statusCode = status.getStatusCode();
		    	if (statusCode != 200) {
		    		result = read(response);
					throw new WeiboException(String.format(status.toString()), statusCode);
				}
				result = read(response);
				return result;
	    	} catch (IOException e) {
				throw new WeiboException(e);
			}
    }
    
    public static HttpClient getHttpClient(Context context){
    	BasicHttpParams httpParameters = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParameters,
                Utility.SET_CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParameters,
                Utility.SET_SOCKET_TIMEOUT);
        HttpClient client = new DefaultHttpClient(httpParameters);
        WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
        if (!wifiManager.isWifiEnabled()) 
        {
            Uri uri = Uri.parse("content://telephony/carriers/preferapn"); 
            Cursor mCursor = context.getContentResolver().query(uri, null, null, null, null);
            if (mCursor != null && mCursor.moveToFirst()) 
            {
                String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy"));
                if (proxyStr != null && proxyStr.trim().length() > 0) 
                {
                	//设置代理
                	HttpHost proxy = new HttpHost(proxyStr, 80);
                    client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
                }
            }
        }
    	return client;
    }
	
    private static void imageToUpload(OutputStream out, Bitmap imgpath)
    	throws WeiboException {
		StringBuilder temp = new StringBuilder();
		temp.append(MP_BOUNDARY).append("\r\n");
		temp.append("Content-Disposition: form-data; name=\"pic\"; filename=\"")
		        .append("news_image").append("\"\r\n");
		String filetype = "image/png";
		temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
		byte[] res = temp.toString().getBytes();
		BufferedInputStream buffInStream = null;
		try {
			out.write(res);
			imgpath.compress(CompressFormat.PNG, 75, out);
			out.write("\r\n".getBytes());
			out.write((END_MP_BOUNDARY).getBytes());
			out.write("\r\n".getBytes());
		} catch (IOException e) {
			throw new WeiboException(e);
		} finally {
			if (null != buffInStream) {
	        try {
	        	buffInStream.close();
	        } catch (IOException e) {
	        	throw new WeiboException(e);
	        }
	    }	
		}
	}


    private static void paramToUpload(OutputStream baos, WeiboParameters params)
    	throws WeiboException, UnsupportedEncodingException {
    	String key = "";
    	for(int loc = 0; loc < params.size(); loc++)
    	{
    		key = params.getKey(loc);
    		StringBuilder temp = new StringBuilder();
    		temp.append(MP_BOUNDARY).append("\r\n");
    		temp.append("content-disposition: form-data; name=\"").append(key)
    		        .append("\"\r\n\r\n");
    		temp.append(URLDecoder.decode(params.getValue(key), "utf-8")).append("\r\n");
    		byte[] res = temp.toString().getBytes();
    		try {
				baos.write(res);
			} catch (IOException e) {
				throw new WeiboException(e);
			}
    	}
	}
    

    //把HttpResponse解析为String
    private static String read(HttpResponse response) throws WeiboException{
    	String result = "";
    	HttpEntity entity = response.getEntity();
		InputStream inputStream;
		try {
			inputStream = entity.getContent();
			ByteArrayOutputStream content = new ByteArrayOutputStream();
			Header header = response.getFirstHeader("Content-Encoding");
			if (header != null && header.getValue().toLowerCase().indexOf("gzip") > -1)
			{
				//GZIP解压缩
				inputStream = new GZIPInputStream(inputStream);
			}
			int readBytesLen = -1;
			byte[] sBuffer = new byte[512];
			while ((readBytesLen = inputStream.read(sBuffer)) != -1) {
				content.write(sBuffer, 0, readBytesLen);
			}
			result = new String(content.toByteArray());
	    	return result;
		} catch (IllegalStateException e) {
			throw new WeiboException(e);
		} catch (IOException e) {
			throw new WeiboException(e);
		}
    }
    
    private static String read(InputStream in) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
        for (String line = r.readLine(); line != null; line = r.readLine()) {
            sb.append(line);
        }
        in.close();
        return sb.toString();
    }
    
    

    public static void clearCookies(Context context) {
        @SuppressWarnings("unused")
        CookieSyncManager cookieSyncMngr =
            CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
    }



    public static void showAlert(Context context, String title, String text) {
        Builder alertBuilder = new Builder(context);
        alertBuilder.setTitle(title);
        alertBuilder.setMessage(text);
        alertBuilder.create().show();
    }
    
    
    public static String encodeParameters(WeiboParameters postParams) {
		if (null == postParams || Utility.isBundleEmpty(postParams)) {
			return "";
		}
		StringBuilder buf = new StringBuilder();
		for (int loci = 0; loci < postParams.size(); loci++) 
		{
			String key = postParams.getKey(loci);
			if (loci!= 0) 
			{
				buf.append("&");
			}
			try 
			{
				buf.append(URLEncoder.encode(key, "UTF-8")).append("=");
				buf.append(URLEncoder.encode(postParams.getValue(key), "UTF-8"));
			} 
			catch (java.io.UnsupportedEncodingException neverHappen) 
			{
			}
		}
		return buf.toString();
	}
    

    public static char[] base64Encode(byte[] data) {
		final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
		char[] out = new char[((data.length + 2) / 3) * 4];
		for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
			boolean quad = false;
			boolean trip = false;
			int val = (0xFF & (int) data[i]);
			val <<= 8;
			if ((i + 1) < data.length) {
				val |= (0xFF & (int) data[i + 1]);
				trip = true;
			}
			val <<= 8;
			if ((i + 2) < data.length) {
				val |= (0xFF & (int) data[i + 2]);
				quad = true;
			}
			out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 1] = alphabet[val & 0x3F];
			val >>= 6;
			out[index + 0] = alphabet[val & 0x3F];
		}
		return out;
	}

	
}
